﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CombineTask
{
    class Program
    {
        //  这里将展示组合任务

        static void Main(string[] args)
        {
            var firstTask = Task.Factory.StartNew(() => {
                Random rnd = new Random();
                DateTime[] dates = new DateTime[100];
                Byte[] buffer = new Byte[8];
                int ctr = dates.GetLowerBound(0);
                while (ctr <= dates.GetUpperBound(0))
                {
                    rnd.NextBytes(buffer);
                    long ticks = BitConverter.ToInt64(buffer, 0);
                    if (ticks <= DateTime.MinValue.Ticks | ticks >= DateTime.MaxValue.Ticks)
                        continue;

                    dates[ctr] = new DateTime(ticks);
                    ctr++;
                }
                return dates;
            });

            Task continuationTask = firstTask.ContinueWith((antecedent) => {
                DateTime[] dates = antecedent.Result;
                DateTime earliest = dates[0];
                DateTime latest = earliest;

                for (int ctr = dates.GetLowerBound(0) + 1; ctr <= dates.GetUpperBound(0); ctr++)
                {
                    if (dates[ctr] < earliest) earliest = dates[ctr];
                    if (dates[ctr] > latest) latest = dates[ctr];
                }
                Console.WriteLine("Earliest date: {0}", earliest);
                Console.WriteLine("Latest date: {0}", latest);
            });
            // Since a console application otherwise terminates, wait for the continuation to complete.
            continuationTask.Wait();


            Console.ReadKey();


            //var firstTask = new Task<int>(() => TaskMethod("First Task", 3));
            //var secondTask = new Task<int>(() => TaskMethod("Second Task", 2));


            //// 给第一个任务设置了一个后续操作 TaskContinuationOptions.OnlyOnRanToCompletion会在当前任务完成后运行
            //firstTask.ContinueWith(t =>
            //{
            //    Console.WriteLine($"The first answer is {t.Result} . Thread id {Thread.CurrentThread.ManagedThreadId}, is thread pool thread:{Thread.CurrentThread.IsThreadPoolThread} ");
            //}, TaskContinuationOptions.OnlyOnRanToCompletion);

            //// 启动两个任务并等待4秒，这足够让两个任务完成
            //firstTask.Start();
            //secondTask.Start(); 
            //Thread.Sleep(TimeSpan.FromSeconds(4));

            //// 给第二个任务运行另一个后续操作并指定 TaskContinuationOptions.ExecuteSynchronously选项来尝试同步执行后续操作
            //// 注：放置在主线程中运行要比放置在线程池中运行要快
            //Task continuation = secondTask.ContinueWith(t =>
            //{
            //    Console.WriteLine($"The second answer is {t.Result} . Thread id {Thread.CurrentThread.ManagedThreadId}, is thread pool thread:{Thread.CurrentThread.IsThreadPoolThread} ");
            //}, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion);

            //continuation.GetAwaiter().OnCompleted(() => Console.WriteLine($"Continuation Task Completed! Thread id {Thread.CurrentThread.ManagedThreadId}, is thread pool thread:{Thread.CurrentThread.IsThreadPoolThread} "));

            //Thread.Sleep(TimeSpan.FromSeconds(2));
            //Console.WriteLine("====================");


            //// 注：通过TaskContinuationOptions.AttachedToParent选项来运行一个所谓的子任务
            ////*********************************************************************************
            //// 子任务必须在父任务运行时创建，并正确的附加给父任务
            //// 这里父任务-Second Task2 ,子任务1-Third Task, 子任务2-"First Task
            ////*********************************************************************************
            //firstTask = new Task<int>(() =>
            //{
            //    var innerTask = Task.Factory.StartNew(() => TaskMethod("Second Task2", 5), TaskCreationOptions.AttachedToParent);
            //    innerTask.ContinueWith(t => TaskMethod("Third Task", 2), TaskContinuationOptions.AttachedToParent);
            //    return TaskMethod("First Task", 2);
            //});

            //firstTask.Start();


            //while (!firstTask.IsCompleted)
            //{
            //    Console.WriteLine(firstTask.Status);
            //    Thread.Sleep(TimeSpan.FromSeconds(0.5));
            //}

            //Console.WriteLine(firstTask.Status);

            Console.ReadKey();
        }

        static int TaskMethod(string name, int seconds)
        {
            Console.WriteLine($"Task {name} is running on a thread id {Thread.CurrentThread.ManagedThreadId}. Is thread pool thread:{Thread.CurrentThread.IsThreadPoolThread}");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));

            return 42 * seconds;
        }



    }
}
